#include <iostream>
#include <ctime>
#include <boost/utility.hpp>

using namespace std;

#define NO_INDICES	81
#define NO_VALUES	10
#define VALUES_MIN		0
#define VALUES_MAX		9
#define INDEX_MIN	1
#define INDEX_MAX	81
#define NO_GROUPS	27

void perm(int* t, int s, int n)
{
	int i, k, l, m;
	for(i = 0; i < n; i++)
	{
		k = rand() % s;
		l = rand() % s;
		m = t[k];
		t[k] = t[l];
		t[l] = m;
	}
}

void getRandomSet(int * t, int min, int s)
{
	int n, i, j, r, c, *d;
	d = new int[s];
//	showIntTab(d, s);
	n = s;
	for(i = 0; i < s; i++)
	{
		r = (rand() % n) + 1;
		//cout << "r=" << r << endl;
		c = 0;
		for(j = 0; (j < s) && (c < r); j++)
		{
			if(d[j] == 0) 
			{
				c++;
			}
		}
//		cout << i << " c=" << c << " r=" << r << " j=" << j <<  endl;
		t[i] = (j - 1) + min;
		d[j - 1] = 1;
		n--;
//		showIntTab(d, s);
	}
	
}

void printIndicesRandom()
{
	int i, t[81];
	cout << NO_INDICES << endl;
	
	for(i = 0; i < 81; i++)
	{
		//cout << i << " ";
		t[i] = i + 1;
	}
	
	//getRandomSet(t, 1, 81);
	perm(t, 81, 10000);
	for(i = 0; i < 81; i++)
	{
		cout << t[i] << " ";
		//t[i] = i;
	}	
	cout << endl;
}

void printIndicesOrdered()
{
	int i;
	cout << NO_INDICES << endl;
	for(i = INDEX_MIN; i <= INDEX_MAX; i++)
	{
		cout << i << " ";
	}
	cout << endl;
}

void printIndicesRevOrdered()
{
	int i;
	cout << NO_INDICES << endl;
	for(i = INDEX_MAX; i >= INDEX_MIN; i--)
	{
		cout << i << " ";
	}
	cout << endl;
}

void printIndicesCombOrdered()
{
	int i;
	cout << NO_INDICES << endl;
	for(i = INDEX_MIN; i <= INDEX_MAX; i = i + 2)
	{
		cout << i << " ";
	}
	for(i = INDEX_MIN + 1; i <= INDEX_MAX; i = i + 2)
	{
		cout << i << " ";
	}
	cout << endl;
}

void printValuesOrdered()
{
	int i;
	cout << NO_VALUES << endl;
	for(i = VALUES_MIN; i <= VALUES_MAX; i++)
	{
		cout << i << " ";
	}
	cout << endl;
}

void printValuesRevOrdered()
{
	int i;
	cout << NO_VALUES << endl;
	for(i = VALUES_MAX; i >= VALUES_MIN; i--)
	{
		cout << i << " ";
	}
	cout << endl;
}

void printGroups()
{
    int i, ii, j, jj;
    //vector<int>* groupVector;// = new vector<int>();
    //Group* group;

    cout << NO_GROUPS << endl;


        
    //rows
    for(i = 1; i < 81; i += 9)
    {
        //groupVector = new vector<int>();
        //group = new GroupUnique(&possibleIndices, &generalPossibleValues);
        cout << "9 U\n";
        for(j = i; j < i + 9; j++)
        {
            //group->getIndicesVector()->push_back(j);
            cout << j << " ";
        }
        //group = new GroupUnique(groupVector, &possibleIndices, &generalPossibleValues);
        //groups.push_back(group);
        cout << endl;
    }
    //cout << endl;	


            
    //columns
    for(i = 1; i < 10; i++)
    {
        //groupVector = new vector<int>();
//        group = new GroupUnique(&possibleIndices, &generalPossibleValues);
		cout << "9 U\n";
        for(j = i; j <= 81; j += 9)
        {
            cout << j << " ";
            //group->getIndicesVector()->push_back(j);
        }
        //group = new GroupUnique(groupVector, &possibleIndices, &generalPossibleValues);
        //groups.push_back(group);
        cout << endl;
    }
    //cout << endl; 

    //squares
    for(i = 1; i <= 81; i += 27)
    {
        for(j = i; j < i + 9; j += 3)
        {
            //groupVector = new vector<int>();
            //group = new GroupUnique(&possibleIndices, &generalPossibleValues);
            cout << "9 U\n";
            for(ii = j; ii < j + 27; ii += 9)
            {
                for(jj = ii; jj < ii + 3; jj++)
                {
                    cout << jj << " ";
                    //group->getIndicesVector()->push_back(jj);
                }
            }
            //group = new GroupUnique(groupVector, &possibleIndices, &generalPossibleValues);

//            groups.push_back(group);
            cout << endl;
        }
    }
    //cout << endl;
            

        

    

           
   
    
    //squares
    for(i = 1; i <= 81; i += 27)
    {
        for(j = i; j < i + 9; j += 3)
        {
            //groupVector = new vector<int>();
            //group = new GroupUnique(&possibleIndices, &generalPossibleValues);
            cout << "9 U\n";
            for(ii = j; ii < j + 27; ii += 9)
            {
                for(jj = ii; jj < ii + 3; jj++)
                {
                    cout << jj << " ";
                    //group->getIndicesVector()->push_back(jj);
                }
            }
            //group = new GroupUnique(groupVector, &possibleIndices, &generalPossibleValues);

//            groups.push_back(group);
            cout << endl;
        }
    }
    //cout << endl;


}

int main() 
{
	srand(time(NULL));
//	printIndicesRandom();
//	printIndicesOrdered();
//	printIndicesRevOrdered();
//	printIndicesCombOrdered();
	printValuesOrdered();
//	printValuesRevOrdered();
	printGroups();
	return 0;
}
